import random as rd
from function import runEventSchedule, runKnapsack
import time
import re
import matplotlib.pyplot as plt
import math


def analysisEvent(N_list=None):
    if N_list is None or len(N_list) == 0:
        # 默认数据测试数据量为10，100，1000，10000四种情况
        N_list = [10, 100, 1000, 10000, 100000]
    for N in N_list:
        # 对每个规模的数据进行测试，并可视化为 数据量-耗时折线图
        x = []
        y = []
        n = N // 10
        while n <= N:
            s = [rd.uniform(0, 1001) for _ in range(n)]
            f = [x + rd.uniform(0.1, 48) for x in s]
            start = time.time()
            runEventSchedule(n, s, f)
            cost = time.time() - start
            x.append(n)
            y.append(cost)
            n += N//10
        print("测试事件个数：", x)
        print("解决问题耗时：", y)
        # 对比
        # x1 = list(range(1, n, n // 10))
        # y1 = [0.00001 * xi + 0.01 * math.log(xi, 2) for xi in x]
        # plt.plot(x1, y1, label="x+logx")
        plt.plot(x, y, label="costLine")
        plt.title('analysis')
        plt.xlabel('X the Data Size')
        plt.ylabel('Y algorithm cost time')
        plt.legend()
        plt.show()


def analysisKnapsack(N=None, cRange=None):
    if cRange is None or len(cRange) == 0:
        cRange = [5, 10, 50, 100, 500, 1000, 10000]  # 不同背包容量
        print("使用默认数据，背包容量列表：", cRange)
    if N is None:
        nRange = list(range(1, 10002, 500))  # 不同物品个数范围
        print("使用默认数据，物品个数列表：", nRange)
    else:
        if 10 <= N < 20:
            nRange = list(range(1, N, N//10))  # 不同物品个数范围
        else:
            nRange = list(range(1, N, N//20))  # 不同物品个数范围
    for c in cRange:
        x = nRange
        y = []
        for n in nRange:
            w = [rd.randint(1, c) for _ in range(n)]
            v = [rd.randint(1, 1000) for _ in range(n)]
            start = time.time()
            runKnapsack(n, c, w, v)
            cost = time.time() - start
            # x.append(n)
            y.append(cost)
        print("背包容量为%d时，测试数据如下:" % c)
        print("物品个数规模N:", x)
        print("花费时间COST:", y)
        plt.plot(x, y, label='costLine')
        plt.title('analysis')
        plt.xlabel('the Knapsack‘s N')
        plt.ylabel('cost seconds when C is %d ' % c)
        plt.legend()
        plt.show()


if __name__ == "__main__":
    choice = input("True.活动安排问题分析\n"
                   "False.一般背包问题分析\n"
                   "请输入您的选择(输入任何非回车字符视为True，直接回车视为False):")
    if choice.__len__() > 0:
        print("您的选择为True")
        tmp_in = input("请输入活动安排问题的数据规模n:\n"
                       "(将测试以n/10为步距到n为止等的事件个数时的算法运行情况，可以是一个整数或整数数组)\n"
                       "(不输入时将测试默认数据)\n")
        # 输入处理
        regx = "[0-9]+"
        list_in = re.findall(regx, tmp_in)
        N_list = [int(x) for x in list_in]
        # 输入处理结束
        analysisEvent(N_list)
    else:
        print("您的选择为False"
              "一般背包问题分析测试")
        tmp_in = input("请输入物品最大范围N(整数，小于10时无效，不输入时将使用默认数据)\n")
        regx = '[0-9]+'
        N_in = re.match(regx, tmp_in)
        try:
            N = int(N_in.group(0))
        except Exception:
            N = None
        tmp_in = input("请输入背包容量测试点(数组,为空时将使用默认数据)\n")
        regx = "([0-9]+(\.[0-9]+)?)"
        list_in = re.findall(regx, tmp_in)
        C_list = [float(x[0]) for x in list_in]
        analysisKnapsack(N, C_list)
